<?php
/**
 * FP_Database class file
 * @package FlickrPhotosetsDB
 */

/**
 * Defines the operations needed for the database.
 * 
 * @package FlickrPhotosetsDB
 * @author Brad Dougherty <bdougherty@gmail.com>
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License 3.0
 */
class FP_MySQLiDB extends FP_Database {
	
	/**
	 * The mysql database link
	 * @var mysql link
	 */
	private $_db;
	
	private $_null = null;
	
	/**
	 * The table we are using
	 * @var string
	 */
	private $_table;
	
	/**
	 * Constructor.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param string $db_host The hostname for the database server
	 * @param string $db_user The username for the database
	 * @param string $db_pass The password for the database
	 * @param string $db_name The name of the database
	 * @param string $db_table The table to be used
	 * @return boolean True if connected
	 */
	public function __construct($db_host, $db_user, $db_pass, $db_name, $db_table) {
		$this->_db = new mysqli($db_host, $db_user, $db_pass, $db_name) or die('connection error');
		$this->_table = $db_table;
	}
	
	/**
	 * Close the connection when we're done with the object.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 */
	public function __destruct() {
		$this->_db->close();
	}
	
	/**
	 * Execute a prepared select statement and return fields in an
	 * associative array.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 */
	private function _execute_select($stmt) {
		$stmt->execute();
		
		$meta = $stmt->result_metadata(); 
		while ($field = $meta->fetch_field()) {
			$var = $field->name;
			$parameters[$var] = &$$var;
		}
		call_user_func_array(array($stmt, 'bind_result'), $parameters);
		
		$return = null;
		while ($stmt->fetch()) {
			$return[] = $parameters;
		}
		$stmt->close();
		
		if (count($return) < 1) return false;
		
		return $return;
	}
	
	/**
	 * Shortcut for preparing a statement.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 */
	private function _prepare($sql) {
		$stmt = $this->_db->prepare($sql) or die("Could not prepare statement<br>".$query."<br>".$this->_db->error);
		return $stmt;
	}
	
	public function custom($sql, $types) {
		$args = array_shift(func_get_args());
		
		$stmt = $this->_prepare($sql);
		call_user_func_array(array($stmt, 'bind_param'), $args);
		$success = $stmt->execute();
		$stmt->close();
		
		return $success;
	}
	
	/**
	 * Gets the user's configuration data.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $uid The user's Facebook ID
	 * @return The configuration array, or false if the user's info wasn't found
	 */
	public function get_info($uid) {
		$stmt = $this->_prepare("select * from {$this->_table} where facebook_uid = ?");
		$stmt->bind_param('s', $uid);
		$config = $this->_execute_select($stmt);
		return $config[0];
	}
	
	/**
	 * Gets the date of the last profile update.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $uid The user's Facebook ID
	 * @return The configuration array, or false if the user's info wasn't found
	 */
	public function get_last_profile_update($uid) {
		$stmt = $this->_prepare("select * from {$this->_table}_log where uid = ? and action = 'profile_update' order by id desc limit 1");
		$stmt->bind_param('s', $uid);
		$result = $this->_execute_select($stmt);
		return $result[0];
	}
	
	/**
	 * Gets the user's profile photo aid.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $uid The user's Facebook ID
	 * @return The configuration array, or false if the user's info wasn't found
	 */
	public function get_profile_aid($uid) {
		$stmt = $this->_prepare("select (? << 32) + (-3 & 0xffffffff) as 'aid'");
		$stmt->_bind_param('s', $uid);
		$stmt->execute();
		$stmt->bind_result($aid);
		$stmt->fetch();
		$stmt->close();
		return $aid;
	}
	
	/**
	 * Get recently created tags.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $minutes The number of minutes to retrieve.
	 */
	public function get_recent_tags($minutes = 10) {
		
	}
	
	/**
	 * Get the UID from an NSID.
	 * 
	 * Use this function to lookup a Facebook user from their Flickr ID.
	 * Returns a string that contains the UID if the user was found.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param string $nsid The Flickr ID
	 * @return int The Facebook UID
	 */
	public function get_uid_from_nsid($nsid) {
		$stmt = $this->_prepare("select facebook_uid from {$this->_table} where flickr_nsid = ?");
		$stmt->bind_param('s', $nsid);
		$result = $this->_execute_select($stmt);
		return $result[0];
	}
	
	/**
	 * Add something to the log.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $uid The uid of the adding user
	 * @return boolean True if the query was successful
	 */
	public function log($uid, $action, $success, $text = '') {
		$success = ($success) ? '1' : '0';
		$stmt = $this->_prepare("insert into {$this->_table}_log (uid, action, success, text) values (?, ?, ?, ?)");
		$stmt->bind_param('ssss', $uid, $action, $success, $text);
		$success = $stmt->execute();
		$stmt->close();
		
		return $success;
	}
	
	/**
	 * Removes the user's Flickr information from the database.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $uid The Facebook user id
	 * @return boolean True if successfully removed
	 */
	public function remove_flickr_auth($uid) {
		$stmt = $this->_prepare("update {$this->_table} set flickr_nsid = ?, flickr_token = ? where facebook_uid = ? limit 1");
		$stmt->bind_param('sss', $this->_null, $this->_null, $uid);
		$success = $stmt->execute();
		$stmt->close();
		
		return $success;
	}
	
	/**
	 * Removes the user from the database.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @return boolean True if the query was successful
	 */
	public function remove_user($uid) {
		$stmt = $this->_prepare("delete from {$this->_table} where facebook_uid = ?");
		$stmt->bind_param('s', $uid);
		$success = $stmt->execute();
		$stmt->close();
		
		// ADD HERE: REMOVE LOG DATA
		
		return $success;
	}
	
	/**
	 * Saves the current configuration to the database ($config).
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param array $config The configuration array
	 * @return boolean True if the query was successful
	 */
	public function save_config($config) {
		$options = array();
		foreach ($config as $option => $value) {
			if (!in_array($option, array('facebook_uid', 'facebook_session_key', 'infinite_session', 'flickr_nsid', 'flickr_token', 'flickr_auth', 'last_seen', 'beta_user', 'tag_beta_user', 'last_photo', 'photosets'))) {
				$options[$option] = $value;
			}
		}
		
		$imploded = Utilities::implodeWithKeys(', ', $options, "'");
		$query = "update {$this->_table} set $imploded where facebook_uid = '{$config['facebook_uid']}'";
		
		if ($this->_db->query($query) === true) {
			return true;
		}
		return false;
	}
	
	/**
	 * Inserts a user's Facebook ID and session key into the database.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $uid The Facebook user id
	 * @param string $facebook_session_key The Facebook session key
	 * @return boolean True if successfully added
	 */
	public function set_facebook_info($uid, $session_key) {
		$stmt = $this->_prepare("insert into {$this->_table} (facebook_uid, facebook_session_key) values (?, ?)");
		$stmt->bind_param('ss', $uid, $session_key);
		$success = $stmt->execute();
		$stmt->close();
		
		return $success;
	}
	
	/**
	 * Updates the user's auth level in the database.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $uid The Facebook user id
	 * @param string $auth_level The single character string representing the auth level (n, r, w, d)
	 * @return boolean True if successfully updated
	 */
	public function set_flickr_auth($uid, $auth_level) {
		$stmt = $this->_prepare("update {$this->_table} set flickr_auth = ? where facebook_uid = ? limit 1");
		$stmt->bind_param('ss', $auth_level, $uid);
		$success = $stmt->execute();
		$stmt->close();
		
		return $success;
	}
	
	/**
	 * Sets the ID of the last photo in the database.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $uid The Facebook user id
	 * @param int $pid The photo id
	 * @return boolean True if the query was successful
	 */
	public function set_last_photo($uid, $pid) {
		
	}
	
	/**
	 * Saves a comma separated list of the user's sets in the database.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $uid The Facebook user id
	 * @param string $photosets A comma separated list of the set ids
	 * @return boolean True if the query was successful
	 */
	public function set_photosets($uid, $photosets) {
		
	}
	
	/**
	 * Stores the user's Flickr token and NSID in the database.
	 * 
	 * @author Brad Dougherty <bdougherty@gmail.com>
	 * @param int $uid The Facebook user id
	 * @param int $nsid The Flickr user id
	 * @param string $token The token returned from Flickr
	 * @return boolean True if successfully added
	 */
	public function store_token($uid, $nsid, $token) {
		$stmt = $this->_prepare("update {$this->_table} set flickr_nsid = ?, flickr_token = ? where facebook_uid = ? limit 1");
		$stmt->bind_param('sss', $nsid, $token, $uid);
		$success = $stmt->execute();
		$stmt->close();
		
		return $success;
	}
	
}

?>